package com.tiancikeji.zaoke.app.service.order.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.transaction.annotation.Transactional;

import com.tiancikeji.zaoke.app.dao.order.OrderDao;
import com.tiancikeji.zaoke.app.model.order.Order;
import com.tiancikeji.zaoke.app.model.order.OrderFood;
import com.tiancikeji.zaoke.app.service.order.OrderService;
import com.tiancikeji.zaoke.app.service.user.UserService;

public class OrderServiceImpl implements OrderService{
	
	private final Log logger = LogFactory.getLog(getClass());

	private OrderDao orderDao;
	
	private UserService userService;
	
	public Order getOrderById(long orderid, long userid){
		return orderDao.getOrderById(orderid);
	}

	public boolean cancelOrder(Order order){
		if(order != null)
			return orderDao.updateOrderState(Order.STATE_CANCEL, order);
		
		return false;
	}

	public List<Order> getActiveOrdersByUserId(long userId) {
		List<Order> result = new ArrayList<Order>();
		List<Order> orders = orderDao.getOrderByUserId(userId);
		
		if(orders != null && orders.size() > 0){
			Set<Long> orderids = new HashSet<Long>();
			for(Order order : orders)
				orderids.add(order.getOrderId());
			
			if(orderids.size() > 0){
				Map<Long, List<OrderFood>> foods = orderDao.getOrderFoodByOrderIds(orderids);

				if(foods != null && foods.size() > 0)
					for(Order order: orders)
						if(foods.containsKey(order.getOrderId())){
							List<OrderFood> tmp = foods.get(order.getOrderId());
							if(tmp != null && tmp.size() > 0){
								order.setOrderFood(tmp);
								result.add(order);
							}
						}
			}
		}
		
		return result;
	}

	public OrderDao getOrderDao() {
		return orderDao;
	}

	public void setOrderDao(OrderDao orderDao) {
		this.orderDao = orderDao;
	}

	public long geneOrderId(Date now, long zoneId) {
		String date = DateFormatUtils.format(now, "yyyyMMdd");
		long id = orderDao.genTodayId(date, zoneId);
		String result = StringUtils.substring(date, 2);
		result += StringUtils.leftPad(new Long(zoneId).toString(), 2, "0");
		result += StringUtils.leftPad(new Long(id).toString(), 4, "0");
		return Long.parseLong(result);
	}

	public boolean createOrder(Order order) {
		List<OrderFood> foods = order.getOrderFood();
		if(foods != null && foods.size() > 0)
			if(orderDao.addFoods(foods))
				return orderDao.addOrder(order);
		return false;
	}

	public boolean payOrder(long orderId) {
		boolean result = false;
		logger.info("pay order for <" + orderId + ">");
		Order order = orderDao.getOrderById(orderId);
		if(order != null){
			int status = Order.STATE_PAID;
			if(order.getZoneId() <= 0)
				status = Order.STATE_PAID_EXPIRE;
			result = orderDao.updateOrderState(status, orderId);
			if(result){
				if(order.getZoneId() <= 0){
					logger.info("update balance for <" + orderId + ">" + " order <" + order + ">");
					result = userService.addBalance(order.getUserId(), order.getSalePrice());
				}
			}
		}
		return result;
	}
	
	@Transactional(rollbackFor=Exception.class, value="txManager")
	public boolean payOrderFromAli(long orderId) {
		return payOrder(orderId);
	}

	public boolean recharge(Order order) {
		return orderDao.addOrder(order);
	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}
}
